﻿namespace GoodAdmin.System;

/// <inheritdoc cref="IDictTypeService"/>
public class DictTypeService: DbRepository<SysDictType>, IDictTypeService, ITransient
{
    private readonly IRedisCacheManager _redisCacheManager;

    public DictTypeService(IRedisCacheManager redisCacheManager)
	{
        _redisCacheManager = redisCacheManager;
    }
    /// <inheritdoc/>
    public async Task Add(DictTypeAddInput input)
    {
        await CheckInput(input);
        if (await InsertAsync(input))
            RefreshCache();
    }
    /// <inheritdoc/>
    public async Task Delete(BaseIdInput input)
    {
        var dictTypeList = await GetDictTypeList();
        if(dictTypeList.Any(d=>d.Id==input.Id && d.SystemMark==CommonConst.SYSTEM))
        {
            throw Oops.Bah(DictErrorCode.D001);
        }
        if (dictTypeList.Any(d => d.ParentId == input.Id))
        {
            throw Oops.Bah(DictErrorCode.D002);
        }
               
        var res = await Context.Ado.UseTranAsync(async () => {
            await DeleteAsync(it => it.Id == input.Id);
            //删除对应字典数据 
            await Context.Deleteable<SysDictData>().Where(it=>it.DictTypeId==input.Id).ExecuteCommandAsync();
            
        });
        if (res.IsSuccess)
        {
            RefreshCache();
        }    
    }
    

    /// <inheritdoc/>
    public async Task Update(DictTypeUpdateInput input)
    {
        await CheckInput(input);
        var dictType = input.Adapt<SysDictType>();
        //if ((await Context.Updateable(dictType).IgnoreColumns(d=>new { d.SystemMark }).ExecuteCommandAsync())>0)
        if(await UpdateAsync(dictType))
            RefreshCache();
    }

    /// <inheritdoc/>
    public async Task<List<SysDictType>> GetDictTypeList()
    {
        var key = CacheConst.SysDictType;
        var list = _redisCacheManager.Get<List<SysDictType>>(key);
        if (list == null)
        {
            list = await Context.Queryable<SysDictType>().OrderBy(it=>it.SortCode).ToListAsync();
            _redisCacheManager.Set(key, list);
        }
        return list;
    }

    /// <inheritdoc/>
    public async Task<List<SysDictType>> GetDictTypeTree()
    {
        var dictTypeList= await GetDictTypeList();
        return ConstructDictTypeTree(dictTypeList);
    }
    /// <inheritdoc/>
    public async Task<long> GetDictTypeId(string Category)
    {
        var dictTypeList = await GetDictTypeList();
        return dictTypeList.Where(it => it.Code.EqualIgnoreCase(Category)).Select(it => it.Id).First();
    }

    #region 私有方法
    private async Task<List<SysDictType>> GetChildList(long Id)
    {
        var result = new List<SysDictType>();
        var list = await GetDictTypeList();
        result = UtilMethod.GetChild(list, result, new List<long> { Id });
        return result;
    }

    private void RefreshCache()
    {
        _redisCacheManager.Remove(CacheConst.SysDictType);
    }

    private async Task CheckInput(SysDictType dict)
    {
        var dictList = await GetDictTypeList();
        if(dict.ParentId > 0 && !dictList.Any(it => it.Id == dict.ParentId))
        {
            throw Oops.Bah(DictErrorCode.D003);
        }
        if(dictList.Any(it=>it.Code==dict.Code && it.Id != dict.Id))
        {
            throw Oops.Bah(DictErrorCode.D005);
        }
        if(dictList.Any(it => it.Name == dict.Name && it.Id != dict.Id))
        {
            throw Oops.Oh(DictErrorCode.D004);
        }
    }

    private List<SysDictType> ConstructDictTypeTree(List<SysDictType> dictTypeList, long ParentId = 0)
    {
        var dictTypes = dictTypeList.Where(it => it.ParentId == ParentId).ToList();

        if (dictTypes.Count == 0) return dictTypes;
        foreach (var dictType in dictTypes)
        {
            dictType.Children = ConstructDictTypeTree(dictTypeList, dictType.Id);
        }
        return dictTypes;
    }
    #endregion
}